package com.bridge.common.utils;

import com.bridge.common.model.vo.DayCompare;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class YXDate {
    private static Calendar getCalendar() {
        TimeZone tz = TimeZone.getDefault();
        return Calendar.getInstance(tz);
    }


    public static List<Date> getDates(String monthStr, Integer... rests) {


        int year = NumberUtil.parseInt(monthStr.split("-")[0], NumberUtil.parseInt(YXDate.getYear(), 2018));
        int month = NumberUtil.parseInt(monthStr.split("-")[1], NumberUtil.parseInt(YXDate.getYear(), 8));


        return getDates(year, month, rests);

    }

    /**
     * 时间段内指定日期的时间列表
     * @param startTime
     * @param endTime
     * @param isWeek
     * @param rests
     * @return
     */
    public static List<Date> getDayWork(Date startTime, Date endTime,boolean isWeek, Integer... rests){
//        开始日期的第一秒
        startTime=YXDate.getTimeDayFirstSecond(startTime);
//        结束日期的最后一秒
        endTime=YXDate.getTimeDayLastSecond(endTime);

        Calendar sCalendar = Calendar.getInstance();
        sCalendar.setTime(startTime);
        List<Date> workDateList = new ArrayList<>();
        while (sCalendar.getTimeInMillis() < endTime.getTime()) {
            for (Integer rest : rests)
                if (isWeek) {
                    if (sCalendar.get(Calendar.DAY_OF_WEEK) == rest) {
                        workDateList.add(sCalendar.getTime());
                        break;
                    }
                } else {
                    if (sCalendar.get(Calendar.DATE) == rest) {
                        workDateList.add(sCalendar.getTime());
                        break;
                    }
                }
            sCalendar.add(Calendar.DATE, 1);
        }

        return workDateList;
    }


    /**
     * 获取指定月周六周日
     *
     * @param year
     * @param month
     * @return
     */
    public static List<Date> getDates(int year, int month) {
        return getDates(year, month, new Integer[]{Calendar.SUNDAY, Calendar.SATURDAY});
    }

    /**
     * 固定时间段内 间隔时间段数组
     *
     * @param startTimeStr
     * @param endTimeStr
     * @param minute
     * @return
     */
    public static List<String> getTimes(String startTimeStr, String endTimeStr, int minute) {
        List<String> times = new ArrayList<>();
        Date startTime = getString2Date("2020-01-01 " + startTimeStr, "yyyy-MM-dd HH:mm");
        Date endTime = getString2Date("2020-01-01 " + endTimeStr, "yyyy-MM-dd HH:mm");
        Date tempStartTime = startTime;
        times.add(getFormatDate2String(tempStartTime, "yyyy-MM-dd HH:mm").split(" ")[1]);
        do {
            tempStartTime = addMinute(tempStartTime, minute);
            times.add(getFormatDate2String(tempStartTime, "yyyy-MM-dd HH:mm").split(" ")[1]);
        }
        while (tempStartTime.getTime() < (endTime.getTime()));


        return times;
    }

    /**
     * java 获取 获取某年某月 所有日期（yyyy-mm-dd格式字符串）
     *
     * @param month
     * @return
     */
    public static List<String> getMonthFullDay(Date month) {
        SimpleDateFormat dateFormatYYYYMMDD = new SimpleDateFormat("yyyy-MM-dd");
        List<String> fullDayList = new ArrayList<>(32);
        // 获得当前日期对象
        Calendar cal = Calendar.getInstance();
        cal.clear();// 清除信息
        cal.setTime(month);
        // 当月1号
        cal.set(Calendar.DAY_OF_MONTH, 1);
        int count = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        for (int j = 1; j <= count; j++) {
            fullDayList.add(dateFormatYYYYMMDD.format(cal.getTime()));
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
        return fullDayList;
    }

    public static List<Date> getMonthFullDayToDate(Date month) {
        List<Date> fullDayList = new ArrayList<>(32);
        // 获得当前日期对象
        Calendar cal = Calendar.getInstance();
        cal.clear();// 清除信息
        cal.setTime(month);
        // 当月1号
        cal.set(Calendar.DAY_OF_MONTH, 1);
        int count = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        for (int j = 1; j <= count; j++) {
            fullDayList.add(cal.getTime());
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
        return fullDayList;
    }

    /**
     * 获取当月总天数
     *
     * @param month
     * @return
     */
    public static int getDayNumByDate(Date month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(month);
        calendar.set(Calendar.DATE, 1);//把日期设置为当月第一天
        calendar.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        int maxDate = calendar.get(Calendar.DATE);
        return maxDate;
    }


    /**
     * 指定时间内星期几的日期
     *
     * @param fromDay
     * @param toDay
     * @param rests
     * @return
     */
    public static List<Date> getDaysFromWeek(Date fromDay, Date toDay, String... rests) {
        List<Date> dates = new ArrayList<>();
        Date startDay = addDay(getFormatDate(fromDay, "yyyy-MM-dd"), -1);

        Date endDay = addDay(getFormatDate(toDay, "yyyy-MM-dd"), 1);

        while (true) {
            try {
                startDay = addDay(startDay, 1);
                int r = startDay.compareTo(endDay);
                if (!isSameDay(startDay, endDay)) {
                    for (int i = 0; i < rests.length; i++) {
                        if (dayForWeek(startDay) == Integer.parseInt(rests[i]))
                            dates.add(startDay);
                    }
                } else {
                    break;
                }

            } catch (Exception e) {
                e.printStackTrace();
                break;
            }
        }


        return dates;
    }

    /**
     * 根据日期得到年份
     *
     * @param date
     * @return
     */
    public static int dayForYear(Date date) {

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        return calendar.get(Calendar.YEAR);

    }

    /**
     * 根据日期得到星期几
     *
     * @param date
     * @return
     */
    public static int dayForWeek(Date date) {

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        return calendar.get(Calendar.DAY_OF_WEEK);

    }

    /**
     * 根据日期得到星期几中文
     *
     * @param date
     * @return
     */
    public static String dayForWeekStr(Date date) {

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        int week=calendar.get(Calendar.DAY_OF_WEEK);

        String weekStr="";
        switch (week){
            case 1:
                weekStr="星期日";
                break;
            case 2:
                weekStr="星期一";
                break;
            case 3:
                weekStr="星期二";
                break;
            case 4:
                weekStr="星期三";
                break;
            case 5:
                weekStr="星期四";
                break;
            case 6:
                weekStr="星期五";
                break;
            case 7:
                weekStr="星期六";
                break;
        }



        return weekStr;

    }

    /**
     * 根据日期得到几月
     *
     * @param date
     * @return
     */
    public static int dayForMonth(Date date) {

        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        return calendar.get(Calendar.MONTH) + 1;

    }

    /**
     * 根据时间获取时，分
     *
     * @param date
     * @return
     */
    public static String hourAndMinuteForDate(Date date) {
        if (StringUtil.isNullOrEmpty(date))
            return "--:--";
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        String hourStr = hour < 10 ? ("0" + hour) : (hour + "");
        int minute = calendar.get(Calendar.MINUTE);
        String minuteStr = minute < 10 ? ("0" + minute) : (minute + "");


        return hourStr + ":" + minuteStr;
    }

    /**
     * 根据时间来获取几点
     *
     * @param date
     * @return
     */
    public static int hourForDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 根据时间来获取几分
     *
     * @param date
     * @return
     */
    public static int minuteForDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 上月的今天的时间
     *
     * @return
     */
    public static Date nextMonthDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        return calendar.getTime();
    }

    /**
     * 下月的今天的时间
     *
     * @return
     */
    public static Date prevMonthDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        return calendar.getTime();
    }

    /**
     * 下月的某一天的时间
     *
     * @return
     */
    public static Date prevMonthDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        return calendar.getTime();
    }

    /**
     * 获取下个月的第几天
     * @param date
     * @param day
     * @return
     */
    public static Date getPrevMonthDate(Date date,Integer day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        return getMonthDate(calendar.getTime(),day);
    }

    /**
     * 获取这个时间段的第几天
     * @param date
     * @param day
     * @return
     */
    public static Date getMonthDate(Date date,Integer day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 时
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        // 分
        calendar.set(Calendar.MINUTE, 0);
        // 秒
        calendar.set(Calendar.SECOND, 0);
        // 毫秒
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    /**
     * 上周的今天的时间
     *
     * @return
     */
    public static Date nextWeekDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.WEEK_OF_YEAR, -1);
        return calendar.getTime();
    }

    /**
     * 昨天的时间
     *
     * @return
     */
    public static Date yesterdayDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_WEEK, -1);
        return calendar.getTime();
    }

    /**
     * 给时间设置时分
     *
     * @param date
     * @param hour
     * @param minite
     * @return
     */
    public static Date setDateTime(Date date, int hour, int minite) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(GregorianCalendar.HOUR, hour);
        calendar.set(GregorianCalendar.MINUTE, minite);
        return calendar.getTime();
    }


    /**
     * 每个月的工作日
     *
     * @param year
     * @param month
     * @return
     */
    public static List<Date> getDates(int year, int month, Integer... rests) {
        List<Date> dates = new ArrayList<Date>();

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DATE, 1);


        while (cal.get(Calendar.YEAR) == year &&
                cal.get(Calendar.MONTH) < month) {
            int day = cal.get(Calendar.DAY_OF_WEEK);
            boolean isWork = true;
            for (int i = 0; i < rests.length; i++) {
                if (day == NumberUtil.parseInt(rests[i])) {
                    isWork = false;
                    break;
                }
            }
            if (isWork)
                dates.add((Date) cal.getTime().clone());

          /*  if(!(day == Calendar.SUNDAY || day == Calendar.SATURDAY)){
                dates.add((Date)cal.getTime().clone());
            }*/

            cal.add(Calendar.DATE, 1);
        }
        return dates;

    }

    public static String remainDateToString(Date startDateStr, Date endDateStr){
        return remainDateToString(YXDate.getFormatDate2String(startDateStr),YXDate.getFormatDate2String(endDateStr));
    }

    /**
     * 计算剩余时间
     * @param startDateStr
     * @param endDateStr
     * @return
     */
    public static String remainDateToString(String startDateStr, String endDateStr){
        java.util.Date startDate = null;
        java.util.Date endDate= null;
        Calendar calS = Calendar.getInstance();
        try {
            startDate = new SimpleDateFormat("yyyy-MM-dd").parse(startDateStr);
        } catch (ParseException e) {
            e.printStackTrace();
            return "";
        }
        try {
            endDate = new SimpleDateFormat("yyyy-MM-dd").parse(endDateStr);
        } catch (ParseException e) {
            e.printStackTrace();
            return "";
        }
        calS.setTime(startDate);
        int startY = calS.get(Calendar.YEAR);
        int startM = calS.get(Calendar.MONTH);
        int startD = calS.get(Calendar.DATE);
        int startDayOfMonth = calS.getActualMaximum(Calendar.DAY_OF_MONTH);

        calS.setTime(endDate);
        int endY = calS.get(Calendar.YEAR);
        int endM = calS.get(Calendar.MONTH);
        //处理2011-01-10到2011-01-10，认为服务为一天
        int endD = calS.get(Calendar.DATE)+1;
        int endDayOfMonth = calS.getActualMaximum(Calendar.DAY_OF_MONTH);

        StringBuilder sBuilder = new StringBuilder();
        if (endDate.compareTo(startDate)<0) {
            return sBuilder.append("过期").toString();
        }
        int lday = endD-startD;
        if (lday<0) {
            endM = endM -1;
            lday = startDayOfMonth+ lday;
        }
        //处理天数问题，如：2011-01-01 到 2013-12-31  2年11个月31天     实际上就是3年
        if (lday == endDayOfMonth) {
            endM = endM+1;
            lday =0;
        }
        int mos = (endY - startY)*12 + (endM- startM);
        int lyear = mos/12;
        int lmonth = mos%12;
        if (lyear >0) {
            sBuilder.append(lyear+"年");
        }
        if (lmonth > 0) {
            sBuilder.append(lmonth+"个月");
        }
        if (lday >0 ) {
            sBuilder.append(lday+"天");
        }
        return sBuilder.toString();
    }

    public static String getYear() {
        return String.valueOf(getCalendar().get(1));
    }

    public static String getYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR) + "";
    }

    public static String getMonth() {
        return strFormat(getCalendar().get(2) + 1);
    }

    public static String getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return String.valueOf(calendar.get(Calendar.MONTH) + 1);
    }

    public static String getDay() {
        return strFormat(getCalendar().get(5));
    }

    public static String getDay(Date date) {
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);
        //二十四小时
        return strFormat(calendar.get(Calendar.DAY_OF_MONTH));
    }

    public static String getFormatDate(String separator) {
        return getYear() + separator + getMonth() + separator + getDay();
    }

    public static String getHour() {
        return strFormat(getCalendar().get(11));
    }

    public static String getHour(Date date) {
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);
        //二十四小时
        return calendar.get(Calendar.HOUR_OF_DAY) + "";
    }

    public static String getMinute() {
        return strFormat(getCalendar().get(12));
    }

    public static String getMinute(Date date) {
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);

        return calendar.get(Calendar.MINUTE) + "";
    }

    public static String getSecond() {
        return strFormat(getCalendar().get(13));
    }

    public static String getDateTime(String s1, String s2) {
        return getYear() + s1 + getMonth() + s1 + getDay() + " " + getHour()
                + s2 + getMinute() + s2 + getSecond();
    }

    public static String getDateTime2(String s1, String s2) {
        return getYear() + s1 + getMonth() + s1 + getDay() + getHour() + s2
                + getMinute() + s2 + getSecond();
    }

    public static String getTime(String s1) {
        return getHour() + s1 + getMinute() + s1 + getSecond();
    }

    public static String getTime() {
        return String.valueOf(System.currentTimeMillis() / 1000L);
    }

    public static String getTime(Date date) {
        return String.valueOf(date.getTime() / 1000L);
    }

    public static String getTimeToday() {
        long now = System.currentTimeMillis() / 1000L;

        return String.valueOf(now);
    }

    private static String strFormat(int data) {
        String str = String.valueOf(data);
        if (data <= 9) {
            str = "0" + str;
        }
        return str;
    }

    /**
     * 根据时间获取时间戳
     *
     * @param date
     * @return
     */
    public static String getDateTime(String date) {
        return getDateTimeFormat(date, "");
    }

    /**
     * 根据时间获取时间戳
     *
     * @param date：时间
     * @param simpleDateFormat：时间格式
     * @return
     */
    public static String getDateTimeFormat(String date, String simpleDateFormat) {
        if ("".equals(TextUtils.dealNull(simpleDateFormat, ""))) {
            simpleDateFormat = "yyyy-MM-dd HH:mm:ss";
        }

        if (date == null || "".equalsIgnoreCase(date))
            return "";

        SimpleDateFormat dateFormat = new SimpleDateFormat(simpleDateFormat);
        Date date2 = null;
        try {
            date2 = dateFormat.parse(date);
        } catch (ParseException e) {
//			e.printStackTrace();
            simpleDateFormat = "yyyy-MM-dd";
            dateFormat = new SimpleDateFormat(simpleDateFormat);
            try {
                date2 = dateFormat.parse(date);
            } catch (ParseException e1) {
                e1.printStackTrace();
            }
        }

        return String.valueOf(date2.getTime() / 1000L);
    }

    public static String TimeStamp2DateTime(String timestampString) {
        Long timestamp = Long.valueOf(Long.parseLong(timestampString));
        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                .format(new Date(timestamp.longValue()));
        return date;
    }


    public static String TimeStamp2Date(String timestampString, String formatStr) {
        Long timestamp = Long.valueOf(timestampString.length() < 13 ? Long
                .parseLong(timestampString) * 1000L : Long
                .parseLong(timestampString));
        String date = new SimpleDateFormat(formatStr).format(new Date(
                timestamp.longValue()));
        return date;
    }


    public static String TimeStamp2Date(String timestampString) {

        return YXDate.TimeStamp2Date(timestampString, "yyyy-MM-dd");

    }


    public static String TimeStamp2Date_month(String timestamp2String) {
        Long timestamp = Long.valueOf(Long.parseLong(timestamp2String) * 1000L);
        String date = new SimpleDateFormat("yyyy-MM").format(new Date(timestamp
                .longValue()));
        return date;
    }

    public static String date2TimeStamp(String date) {
        try {
            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
            Date s = dateformat.parse(date);
            return String.valueOf(s.getTime() / 1000L);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String dateTime2TimeStamp(String date) {
        try {
            SimpleDateFormat dateformat = new SimpleDateFormat(
                    "yyyy-MM-dd HH:mm:ss");
            Date s = dateformat.parse(date);
            return String.valueOf(s.getTime() / 1000L);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getTimeDayLastSecond() {
        return dateTime2TimeStamp(TimeStamp2Date(String.valueOf(System
                .currentTimeMillis())) + " 23:59:59");
    }

    public static String getMonthTime(int month) {
        Calendar cal = Calendar.getInstance();
        cal.add(2, month);
        String timeStamp = String.valueOf(cal.getTimeInMillis() / 1000L);
        return timeStamp;
    }

    public static String getDayTime(int days) {
        Calendar cal = Calendar.getInstance();
        cal.add(6, days);
        String timeStamp = String.valueOf(cal.getTimeInMillis() / 1000L);
        return timeStamp;
    }

    public static String getYearTime(int years) {
        Calendar cal = Calendar.getInstance();
        cal.add(1, years);
        String timeStamp = String.valueOf(cal.getTimeInMillis() / 1000L);
        return timeStamp;
    }

    public static String getYearTime(long timeStamp1, int years) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(timeStamp1 * 1000L);
        cal.add(1, years);
        String timeStamp = String.valueOf(cal.getTimeInMillis() / 1000L);
        return timeStamp;
    }

    public static int lateDays(long time) {
        Calendar c = Calendar.getInstance();
        Calendar nowTime = Calendar.getInstance();
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date date = format.parse(format.format(Long.valueOf(String.valueOf(
                    time).length() < 13 ? time * 1000L : time)));
            c.setTime(date);
            long now = System.currentTimeMillis();
            Date date2 = format.parse(format.format(Long.valueOf(now)));
            nowTime.setTime(date2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return countDays(c, nowTime);
    }

    public static int lateDays(long time1, long time2) {
        Calendar c = Calendar.getInstance();
        Calendar nowTime = Calendar.getInstance();
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date date = format.parse(format.format(Long.valueOf(String.valueOf(
                    time1).length() < 13 ? time1 * 1000L : time1)));
            c.setTime(date);

            Date date2 = format.parse(format.format(Long.valueOf(String
                    .valueOf(time2).length() < 13 ? time2 * 1000L : time2)));
            nowTime.setTime(date2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return countDays(c, nowTime);
    }

    public static int countDays(Calendar c_b, Calendar c_e) {
        int days = 0;
        while (c_b.before(c_e)) {
            days++;
            c_b.add(6, 1);
        }
        return days;
    }

    public static String getOffsetMonthDate(Date protoDate, int monthOffset) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(protoDate);
        cal.add(2, -monthOffset);
        Date date = cal.getTime();
        return new SimpleDateFormat("yyyy-MM").format(date);
    }

    public static String getLastMonth(int month) {
        return getYear() + "-" + strFormat(getCalendar().get(2) + 1 - month);
    }


    /**
     * @param date
     * @param addMonth
     * @return
     */
    public static Date addMonths(Date date, int addMonth) {

        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(Calendar.MONTH, addMonth);

        return gc.getTime();

    }

    public static Date addMonths(String dateStr, int addMonth) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return YXDate.addMonths(sdf.parse(dateStr), addMonth);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return YXDate.addMonths(addMonth);

    }

    /**
     * 添加月
     *
     * @param addMonth 添加或减少月数
     * @return
     */

    public static Date addMonths(int addMonth) {
        return YXDate.addMonths(new Date(), addMonth);
    }


    /**
     * 根据时间获取当前月有几天
     *
     * @param date
     * @return
     */
    public static int daysOfMonth(Date date) {
        if (date == null)
            return 0;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 当前月开始时间
     *
     * @param date
     * @return
     */

    public static Date getTimeMonthFirstSecond(Date date) {


        if (date == null)
            return null;

        String dateStr = new SimpleDateFormat("yyyy-MM").format(date);
        dateStr = dateStr + "-01";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {

            return sdf.parse(dateStr + " 00:00:00");
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return date;

    }

    /**
     * 月的最后一秒
     *
     * @param date
     * @return
     */

    public static Date getTimeMonthLastSecond(Date date) {


        if (date == null)
            return null;

        String dateStr = new SimpleDateFormat("yyyy-MM").format(date);

        dateStr = dateStr + "-01";


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date last = sdf.parse(dateStr + " 23:59:59");
            return YXDate.addDay(YXDate.addMonths(last, 1), -1);


        } catch (ParseException e) {

            e.printStackTrace();
        }
        return date;

    }


    /**
     * 一天的最后一刻
     *
     * @param date 日期源
     * @return 处理后的日期
     */
    public static Date getTimeDayLastSecond(Date date) {

        if (date == null)
            return null;

        String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(date);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {

            return sdf.parse(dateStr + " 23:59:59");
        } catch (ParseException e) {

            e.printStackTrace();
        }
        return date;

    }


    /**
     * 得到某一天指定时间
     *
     * @param date 日期
     * @param hms  时间 hh:mm:ss
     * @return
     */

    public static Date getTimeDayBySecond(Date date, String hms) {

        if (date == null)
            return null;

        String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(date);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {

            return sdf.parse(dateStr + " " + hms);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return date;
    }


    /**
     * 一天的第一刻
     *
     * @param date 日期源
     * @return 处理后的日期
     */
    public static Date getTimeDayFirstSecond(Date date) {

        if (date == null)
            return null;

        String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(date);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {

            return sdf.parse(dateStr + " 00:00:00");
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return date;
    }


    public static Date addSeconds(int second) {
        return YXDate.addSeconds(new Date(), second);

    }

    /**
     * 日期加秒数
     *
     * @param date
     * @param second
     * @return
     */

    public static Date addSeconds(Date date, int second) {

        if (date == null)
            date = new Date();

        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(Calendar.SECOND, second);

        return gc.getTime();

    }

    /**
     * 日期加分钟数
     *
     * @param date
     * @param minute
     * @return
     */

    public static Date addMinute(Date date, int minute) {

        if (date == null)
            date = new Date();

        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(Calendar.MINUTE, minute);


        return gc.getTime();

    }

    /**
     * 日期加小时数
     *
     * @param date
     * @param hour
     * @return
     */

    public static Date addHours(Date date, int hour) {

        if (date == null)
            date = new Date();

        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(Calendar.HOUR, hour);


        return gc.getTime();

    }

    /**
     * 日期加天数
     *
     * @param date   日期源
     * @param dayNum 需要变动的天数
     * @return 处理后的日期
     */
    public static Date addDay(Date date, int dayNum) {
        if (date == null)
            date = new Date();
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(Calendar.DATE, dayNum);

        return gc.getTime();
    }

    /**
     * 日期加天数
     *
     * @param dayNum 需要变动的天数
     * @return 处理后的日期
     */
    public static Date addDay(int dayNum) {
        return YXDate.addDay(new Date(), dayNum);

    }

    /**
     * 两个日期相差几小时（向上取整）
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    public static int getHourSub(Date beginDate, Date endDate) {
        if (beginDate == null || endDate == null)
            return 0;
        long time1 = beginDate.getTime();
        long time2 = endDate.getTime();
        int subHour = (int) Math.floor((time2 - time1) / 1000 / 60 / 60);

        return subHour;
    }

    public static double getHourAndMinSub(Date beginDate, Date endDate) {
        long[] subData = getSubData(beginDate, endDate);
        long min = subData[1];
        long hour = subData[2];
        double hours = (int) hour;
        if (min == 30)
            hours = hours + 0.5;

        return hours;

    }

    /**
     * 获取两个时间差的分钟差
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    public static double getMinuteSub(Date beginDate, Date endDate) {
        return getSubData(beginDate, endDate)[1];
    }

    /**
     * 把对象存在集合中 分别是  秒，分钟，小时
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    public static long[] getSubData(Date beginDate, Date endDate) {
        if (beginDate == null || endDate == null)
            return null;
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long diff = endDate.getTime() - beginDate.getTime();
        long hour = diff % nd / nh;
        long min = diff % nd % nh / nm;
        long[] time = {diff, min, hour};
        return time;
    }

    /**
     * 两个日期的相差天数
     *
     * @param beginDate 起始日期
     * @param endDate   截止日期
     * @return
     */
    public static int getDaySub(Date beginDate, Date endDate) {

        if (beginDate == null || endDate == null)
            return 0;
        int day = 0;
        try {
            day = NumberUtil.parseInt((endDate.getTime() - beginDate.getTime())
                    / (24 * 60 * 60 * 1000));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return day + 1;
    }

    /**
     * 两个时间相差多少月
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getMonthSub(Date startDate, Date endDate) {
        Calendar calStart = new GregorianCalendar();
        calStart.setTime(startDate);
        Calendar calEnd = new GregorianCalendar();
        calEnd.setTime(endDate);
        int c = (calEnd.get(Calendar.YEAR) - calStart.get(Calendar.YEAR)) * 12
                + calEnd.get(Calendar.MONTH) - calStart.get(Calendar.MONTH);
        return c;
    }

    public static Date getDate2TimeStamp(String timestampString) {

        Long timestamp = Long.valueOf(Long.parseLong(timestampString));
        return new Date(timestamp.longValue());

    }

    public static String getFormatDate2String(Date date) {

        return getFormatDate2String(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getFormatDate2String1(Date date) {

        return getFormatDate2String(date, "yyyy-MM-dd");
    }


    public static String getFormatDate2String(Date date, String formatStr) {
        if (date == null)
            return "";

        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);

        return sdf.format(date);

    }


    public static Date getFormatDate(Date date, String formatStr) {
        if (date == null)
            date = new Date();
        return YXDate.getString2Date(YXDate.getFormatDate2String(date), formatStr);


    }


    public static Date getString2Date(String dateString) {

        if (dateString == null || "".equals(dateString))
            return null;


        return getString2Date(dateString, "yyyy-MM-dd HH:mm:ss");

    }


    public static Date getString2Date(String dateString, String formatStr) {

        try {
            SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
            return sdf.parse(dateString);
        } catch (ParseException e) {

        }
        return YXDate.getFormatDate(new Date(), formatStr);

    }

    public static int compareDay(Date startDate, Date endDate) {

        String startDateStr = new SimpleDateFormat("yyyy-MM-dd").format(startDate);
        String endDateStr = new SimpleDateFormat("yyyy-MM-dd").format(endDate);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            startDate = sdf.parse(startDateStr);
            endDate = sdf.parse(endDateStr);

            return startDate.compareTo(endDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }


        return -1;

    }

    /**
     * 获取前几天的时间
     *
     * @param before：前几天
     * @return
     */
    public static Date getBeforeDate(int before) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, before);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String mDateTime = formatter.format(c.getTime());
        Date date = null;
        try {
            date = formatter.parse(mDateTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 获取当前月的第一天
     *
     * @return
     * @paramdate
     * @paramformatStr
     */
    public static String getFisrtDayOfMonth() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String firstDay = sdf.format(new Date());
        return firstDay + "-01";
    }

    /**
     * 获取当前日期
     *
     * @return
     * @paramdate
     * @paramformatStr
     */
    public static String getNowOfMonth() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(new Date());
    }


    /**
     * 检测是否同一天
     *
     * @param one
     * @param two
     * @return
     */
    public static boolean isSameDay(Date one, Date two) {

        return YXDate.isSameTime(one, two, "yyyy-MM-dd");

    }

    /**
     * 检测是否同一时刻
     *
     * @param one
     * @param two
     * @return
     */
    public static boolean isSameTime(Date one, Date two, String formatString) {
        one = YXDate.getFormatDate(one, formatString);
        two = YXDate.getFormatDate(two, formatString);

        return one.compareTo(two) == 0;

    }

    /**
     * 计算2个日期之间相差的  相差多少年月日
     * 比如：2011-02-02 到  2017-03-02 相差 6年，1个月，0天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static DayCompare dayComparePrecise(Date fromDate, Date toDate) {
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);

        int fromYear = from.get(Calendar.YEAR);
        int fromMonth = from.get(Calendar.MONTH);
        int fromDay = from.get(Calendar.DAY_OF_MONTH);

        int toYear = to.get(Calendar.YEAR);
        int toMonth = to.get(Calendar.MONTH);
        int toDay = to.get(Calendar.DAY_OF_MONTH);
        int year = toYear - fromYear;
        int month = toMonth - fromMonth;
        int day = toDay - fromDay;
        return DayCompare.builder().day(day).month(month).year(year).build();
    }

    /**
     * 计算2个日期之间相差的  以年、月、日为单位，各自计算结果是多少
     * 比如：2011-02-02 到  2017-03-02
     * 以年为单位相差为：6年
     * 以月为单位相差为：73个月
     * 以日为单位相差为：2220天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static DayCompare dayCompare(Date fromDate, Date toDate) {
        Calendar from = Calendar.getInstance();
        from.setTime(fromDate);
        Calendar to = Calendar.getInstance();
        to.setTime(toDate);
        //只要年月
        int fromYear = from.get(Calendar.YEAR);
        int fromMonth = from.get(Calendar.MONTH);

        int toYear = to.get(Calendar.YEAR);
        int toMonth = to.get(Calendar.MONTH);

        int year = toYear - fromYear;
        int month = toYear * 12 + toMonth - (fromYear * 12 + fromMonth);
        int day = (int) ((to.getTimeInMillis() - from.getTimeInMillis()) / (24 * 3600 * 1000));
        return DayCompare.builder().day(day).month(month).year(year).build();
    }

    /**
     * 计算2个日期相差多少年
     * 列：2011-02-02  ~  2017-03-02 大约相差 6.1 年
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static String yearCompare(Date fromDate, Date toDate) {
        DayCompare result = dayComparePrecise(fromDate, toDate);
        double month = result.getMonth();
        double year = result.getYear();
        //返回2位小数，并且四舍五入
        DecimalFormat df = new DecimalFormat("######");
        return df.format(year + month / 12);
    }

    /**
     * 根据开始时间和结束时间获取特定时间端的时间
     *
     * @param start
     * @param end
     */
    public static List<Date> screenMonthByDay(Date start, Date end, String[] days) {
        List<Date> dates = new ArrayList<>();
        //获取两个时间端的月份差
        int month = getMonthSub(start, end);
        if (month < 0)
            return dates;
        //获取两个时间端的月份差
        int loop = month+1;

        for(int i=0;i<loop;i++){
            Calendar calendar1 = Calendar.getInstance();
            calendar1.setTime(start);
            int startMonth = calendar1.get(Calendar.MONTH);//最开始的月份
            calendar1.set(Calendar.MONTH,startMonth+i);
            int maxDay = calendar1.getActualMaximum(Calendar.DAY_OF_MONTH);//最大的一天
            for(String day :days){
                if(Integer.valueOf(day) > maxDay){
                    continue;
                }
                calendar1.set(Calendar.DAY_OF_MONTH,Integer.valueOf(day));
                if(start.getTime()<=calendar1.getTime().getTime() && calendar1.getTime().getTime()<=end.getTime()){
                    dates.add(calendar1.getTime());
                }
            }

        }

        return dates;
    }



    public static void main(String[] args) {
//        String startTimeStr = "2020-04-16 10:00:00";
//        Date startTime = getString2Date(startTimeStr, "yyyy-MM-dd");
//        String endTimeStr = "2020-06-16 10:00:00";
//        Date endTime = getString2Date(endTimeStr, "yyyy-MM-dd");
//        String startHour = "10:00";
//        String endHour = "14:30";
//        int intervalTime = 1;
//
//
//        getMonthDayHour(startTime, endTime, startHour, endHour, intervalTime,false, new Integer[]{1,2});


        //System.out.println(getFormatDate2String(YXDate.addDay(YXDate.getString2Date("2014-02-28 15:59:59"),1314)));

        //System.out.println(YXDate.getDaySub(new Date(),YXDate.getString2Date("2017-10-04 00:00:01")));
//        System.out.println(YXDate.getDaySub(new Date(), YXDate.getString2Date("2018-01-28 00:00:01")));
//        System.out.println(YXDate.getDaySub(new Date(), YXDate.getString2Date("2018-01-13 00:00:01")));

//        List<Date> dates1 = screenMonthByDay(YXDate.getString2Date("2019-02-01 00:00:01"), YXDate.getString2Date("2019-06-3 00:00:01"), new String[]{"30","31"});
//
//        List<Date> dates = YXDate.getDaysFromWeek(YXDate.getString2Date("2019-05-01 00:00:01"),YXDate.getString2Date("2019-05-31 00:00:01"), new String[]{"1","2","3","4","5","6","7"});
//        for (Date date:dates1) {
//            System.out.println(YXDate.getFormatDate2String(date));
//        }
//
//        double hourSub = YXDate.getHourAndMinSub(YXDate.getString2Date("2019-05-01 02:00:01"), YXDate.getString2Date("2019-05-01 03:00:01"));
//        System.out.println("hourSub===>"+hourSub);
//
//        getTimes("08:00", "20:00", 30);

//Date nowTime=new Date();
//        getMonthFullDay(nowTime);
//        Calendar cal = Calendar.getInstance();
//        获取某月最小天数
//        设置日历中月份的最小天数
//        cal.set(Calendar.DAY_OF_MONTH, 2);

    }


}
